package com.biovr.backend.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.springframework.beans.factory.annotation.Value;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by monodev on 2017/4/30.
 */
@org.springframework.stereotype.Component
public class QrCodeUtils {
    //定义的上传路径
    @Value("${web.qcode-path}")
    private String qCodePath;

    private  final int BLACK = 0xFF000000;
    private  final int WHITE = 0xFFFFFFFF;
    /**
     * 把生成的二维码存入到图片中
     * @param matrix zxing包下的二维码类
     * @return
     */
    private  BufferedImage toBufferedImage(BitMatrix matrix) {
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
            }
        }
        return image;
    }
    /**
     * 生成二维码并写入文件
     * @param content 扫描二维码的内容
     * @param fileName  二维码文件名
     * @throws Exception
     */

    public  void saveQRCodeToFile(String content, String fileName, String text)
            throws Exception {
        MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
        @SuppressWarnings("rawtypes")
        Map hints = new HashMap();
        //设置UTF-8， 防止中文乱码
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        //设置二维码四周白色区域的大小
        hints.put(EncodeHintType.MARGIN,1);
        //设置二维码的容错性
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        //画二维码
        BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 400, 400, hints);
        BufferedImage image = toBufferedImage(bitMatrix);
        File file =new File(qCodePath+fileName);
        if (!ImageIO.write(image, "jpg",file)) {
            throw new IOException("Could not write an image of format " + "jpg" + " to " + file);
        }

//        if (  !text.equals(null) || !text.equals("")){
//            putText(text,file,5,Color.black,16);
//        }

    }


  /**
   * 生成二维码并使用Base64编码
   * @param content
   * @throws Exception
   */

  public  String getBase64QRCode(String content)
    throws Exception {
    MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
    @SuppressWarnings("rawtypes")
    Map hints = new HashMap();
    //设置UTF-8， 防止中文乱码
    hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
    //设置二维码四周白色区域的大小
    hints.put(EncodeHintType.MARGIN,1);
    //设置二维码的容错性
    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
    //画二维码
    BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 400, 400, hints);
    BufferedImage image = toBufferedImage(bitMatrix);
    byte[] bytes =imageToBytes(image,"jpg");
    String base64String = Base64.getEncoder().encodeToString(bytes);
    return base64String;
  }
    /**
     * 给二维码图片加上文字
     * @param text 文字
     * @param qrFile  二维码文件
     * @param fontStyle
     * @param color
     * @param fontSize
     */
    private  void putText(String text, File qrFile, int fontStyle, Color color, int fontSize) throws Exception {
        text = "BioVR:"+text;
        text = new String(text.getBytes(), "utf-8");
        Image src = ImageIO.read(qrFile);
        int imageW = src.getWidth(null);
        int imageH = src.getHeight(null);
        BufferedImage image = new BufferedImage(imageW, imageH, BufferedImage.TYPE_INT_RGB);
        Graphics g = image.createGraphics();
        g.drawImage(src, 0, 0, imageW, imageH, null);

        //设置画笔的颜色
        g.setColor(color);
        //设置字体
        Font font = new Font("宋体", fontStyle, fontSize);
        FontMetrics metrics = g.getFontMetrics(font);
        //文字在图片中的坐标 这里设置在中间
        int startX = (400 - metrics.stringWidth(text)) / 2;
        int startY = 200;
        g.setFont(font);
        //获得宽、高画底色
        g.setColor(Color.white);
        g.fillRect(startX,startY,g.getFontMetrics().stringWidth(text),g.getFontMetrics().getHeight());
        g.setColor(Color.black);
        g.drawString(text, startX, startY+g.getFontMetrics().getAscent());
        g.dispose();
        FileOutputStream out = new FileOutputStream(qrFile);
        ImageIO.write(image, "JPEG", out);
        out.close();
        System.out.println("image press success");
    }


  /**
   * 转换BufferedImage 数据为byte数组
   *
   * @param bImage
   * Image对象
   * @param format
   * image格式字符串.如"gif","png"
   * @return byte数组
   */
  public static byte[] imageToBytes(BufferedImage bImage, String format) {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try {
      ImageIO.write(bImage, format, out);
    } catch (IOException e) {
      e.printStackTrace();
    }
    return out.toByteArray();
  }

  /**
   * 转换byte数组为Image
   *
   * @param bytes
   * @return Image
   */
  public static Image bytesToImage(byte[] bytes) {
    Image image = Toolkit.getDefaultToolkit().createImage(bytes);
    try {
      MediaTracker mt = new MediaTracker(new Label());
      mt.addImage(image, 0);
      mt.waitForAll();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    return image;
  }

    public    void deleteQrcode(String qcodeFileName) throws FileNotFoundException{
        File qCodeFile =  new File(qCodePath+qcodeFileName);
        if (qCodeFile.exists()){
            qCodeFile.delete();
        }
    }
}
